#include "NetworkClient.h"
#include "common.h"

using namespace std;

void formatMessage(const char* src, char* dest, size_t destSize) {
    if (!src || !dest || destSize < 75) return;

    dest[0] = 0xFE;
    dest[1] = 0xFE;
    
    for(int i = 0;i<70;i++){
        dest[i+2] = src[i];
    }
    // size_t copySize = min(strlen(src), size_t(70));
    // memcpy(dest + 2, src, copySize);
    // memset(dest + 2 + copySize, 0, 70 - copySize);

    dest[74] = 0xFD;
    dest[73] = 0xFD;

    char checksum = dest[0];
    for(int i = 1; i < 72; i++) {
        checksum ^= dest[i]; 
    }
    dest[72] = checksum;
}

NetworkClient::NetworkClient(const string& serverIp, int port)
    : m_socketFd(-1)
    , m_serverIp(serverIp)
    , m_port(port)
    , m_connected(false) {
}

NetworkClient::~NetworkClient() {
    disconnect();
}

void NetworkClient::setIp(const string Ip){
    this->m_serverIp = Ip;
}

bool NetworkClient::connect() {
    if (m_connected) return true;

    m_socketFd = socket(AF_INET, SOCK_STREAM, 0);
    if (m_socketFd < 0) return false;

    sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(m_port);
    
    if (inet_pton(AF_INET, m_serverIp.c_str(), &serverAddr.sin_addr) <= 0) {
        close(m_socketFd);
        m_socketFd = -1;
        return false;
    }

    if (::connect(m_socketFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        close(m_socketFd);
        m_socketFd = -1;
        return false;
    }

    m_connected = true;
    return true;
}

void NetworkClient::disconnect() {
    if (!m_connected) return;

    if (m_socketFd != -1) {
        close(m_socketFd);
        m_socketFd = -1;
    }
    
    m_connected = false;
}

bool NetworkClient::isConnected() const {
    return m_connected;
}

bool NetworkClient::sendMessage(const string& message) {
    if (!m_connected) return false;
    
    return send(m_socketFd, message.c_str(), message.length(), 0) == static_cast<ssize_t>(message.length());
}

void NetworkClient::func(const char message[]) {
    // cout<<"message:"<<endl;

    // for(int i = 0; i < 75;i++){
    //     cout<<hex<<static_cast<int>(message[i])<<" ";
    // }
    // cout<<endl;
    if (!m_connected) {
        throw runtime_error("Not connected to server");
    }
    
    char buffer[75] = {0};
    
    formatMessage(message, buffer, sizeof(buffer));
    if(buffer[2] == 0x00){
        buffer[2] = 0x01;
    }
    ssize_t bytesSent = send(m_socketFd, buffer, sizeof(buffer), 0);
    if (bytesSent != sizeof(buffer)) {
        throw runtime_error("Failed to send complete formatted message");
    }
}